package org.wejob.core.log;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;

public class ConcurrentList<N> {
    //写同步,读不同步

    volatile Node head;
    AtomicBoolean writeLock;
    int size;
    public ConcurrentList(){
        this.writeLock=new AtomicBoolean(false);
        this.size=0;
    }
    public void put(N val){
        while (this.writeLock.compareAndSet(false, true)) {
            Node node=new Node<N>(val);
            node.next=this.head;
            this.head=node;
            this.size++;
            this.writeLock.set(false);
            break;
        }
    }

    public boolean remove(N val){
        while (this.writeLock.compareAndSet(false, true)) {
            if(this.head==null)
                return false;
            if(this.head.val.equals(val)){
                this.head=this.head.next;
                return true;
            }
            Node<N> pre=head;
            Node<N> cur=head.next;
            while(cur!=null){
                if(cur.val.equals(val)){
                    pre.next=cur.next;
                    return true;
                }
                pre=cur;
                cur=cur.next;
            }
            return false;
        }
        return false;
    }

    public N poll(){
        while (this.writeLock.compareAndSet(false, true)) {
            if(this.head==null)
                return null;
            Node node=this.head;
            this.head=node.next;
            this.size--;
            this.writeLock.set(false);
            return (N) node.val;
        }
        return null;
    }

    public void forEach(Consumer<N> action){
        if(this.head==null)
            return;
        Node<N> cur=head;
        while(cur!=null){
            action.accept(cur.val);
            cur=cur.next;
        }
    }

    public boolean isEmpty(){
        return this.size==0;
    }
    class Node<T extends N>{
        T val;
        Node<T> next;
        public Node(T val){
            this.val=val;
        }
    }

}
